package com.ayh.campusfun.controller.api.v1;

import cn.hutool.core.bean.BeanUtil;
import com.ayh.campusfun.common.CommonResult;
import com.ayh.campusfun.common.core.jwt.JWTUtils;
import com.ayh.campusfun.common.exception.http.CaptchaCodeException;
import com.ayh.campusfun.common.exception.http.CommenException;
import com.ayh.campusfun.common.exception.http.PasswordOrUserErrorException;
import com.ayh.campusfun.dto.LoginDTO;
import com.ayh.campusfun.dto.LoginForOtherDTO;
import com.ayh.campusfun.dto.RegisterDTO;
import com.ayh.campusfun.entity.Users;
import com.ayh.campusfun.service.UsersService;
import com.ayh.campusfun.vo.UsersVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.axis.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 用户表(Users)表控制层
 *
 * @author ayh
 * @since 2021-03-20 20:42:42
 */
@RestController
@RequestMapping("users")
@Slf4j
public class UsersController {
    /**
     * 服务对象
     */
    @Autowired
    private UsersService usersService;

    @Autowired
    private JWTUtils jwtUtils;

    @Autowired
    RedisTemplate<String, Object> redisTemplate;


    @PostMapping("/login")
    public CommonResult login (@RequestBody LoginDTO loginDTO){
//        System.out.println(loginDTO);
        Map<String, Object> login = usersService.login(loginDTO.getAccount(), loginDTO.getPassword(), loginDTO.getCaptchaKey(), loginDTO.getCaptchaCode());
        return CommonResult.success(login);
    }

    @PostMapping("/refreshToken")
    public CommonResult refreshToken(HttpServletRequest request){
        String uidFromRequest = jwtUtils.getUidFromRequest(request);
        String nameFromRequest = jwtUtils.getNameFromRequest(request);
        String avatarFromRequest = jwtUtils.getAvatarFromRequest(request);
        Users usersBuild = Users.builder()
                .uid(uidFromRequest)
                .nickName(nameFromRequest)
                .avatarUrl(avatarFromRequest)
                .build();
        String token = jwtUtils.getToken(usersBuild);
        redisTemplate.delete(jwtUtils.getTokenFromRequest(request));
        redisTemplate.opsForValue().set(token,usersBuild,3, TimeUnit.DAYS);
        return CommonResult.success(token);
    }

    @PostMapping("/refreshAuthCode")
    public CommonResult refreshAuthCode (String email, String codeKey){
        String key = usersService.refreshAuthCode(email, codeKey);
        return CommonResult.success(key);
    }

    @PostMapping("/getAuthCode")
    public CommonResult getAuthCode (String email){
        String key = usersService.getAuthCode(email);
        return CommonResult.success(key);
    }

    @PostMapping("/register")
    @Validated
    public CommonResult register(@Validated RegisterDTO registerDTO){
        try{
            Long i = usersService.register(registerDTO);
            return CommonResult.success(i);
        }catch (DuplicateKeyException e){
            throw new CommenException(7000);
        }
    }

    @PostMapping("/loginForOther")
    public CommonResult loginForOther (@RequestBody LoginForOtherDTO loginForOtherDTO){
        Map<String, Object> map = usersService.loginForOther(loginForOtherDTO);
        return CommonResult.success(map);
    }

    @PostMapping(value = "/findUserMassage",produces = "application/json")
    public CommonResult getFunList(Long userId, Long uid){
        Map<String,Object> map = new HashMap<>();
        map.put("id",userId);
        map.put("uid",uid);
        return CommonResult.success(usersService.findByParam(map));
    }

    @PostMapping(value = "/updatePassword",produces = "application/json")
    public CommonResult updatePassword(String account,String sourcePassword,Integer type, String password,String code){
        Map<String,Object> map = new HashMap<>();
        map.put("uid",account);
        Users users = usersService.findByParam(map);
        if(users==null){
            throw new PasswordOrUserErrorException(60006);
        }
        if(type==1){
            String sourceCode = (String) redisTemplate.opsForValue().get(users.getEmail());
            if (StringUtils.isEmpty(sourceCode)) {
                throw new CaptchaCodeException(60005);
            }
            if(!code.equals(sourceCode)){
                throw new CaptchaCodeException(60004);
            }
        }else if(type==2){
            if(!sourcePassword.equals(users.getPassword())){
                throw new PasswordOrUserErrorException(60006);
            }
        }else {
            throw new RuntimeException();
        }
        users.setPassword(password);
        usersService.updateById(users);
        return CommonResult.successNoData();
    }

    @PostMapping(value = "/setCodeByEmail",produces = "application/json")
    public CommonResult setCodeByEmail(String account){
        Map<String,Object> map = new HashMap<>();
        map.put("uid",account);
        Users users = usersService.findByParam(map);
        if(users==null){
            throw new PasswordOrUserErrorException(60006);
        }
        if(users.getEmail()!=null){
            usersService.getAuthCode(users.getEmail());
        }else {
            throw new PasswordOrUserErrorException(60006);
        }
        return CommonResult.successNoData();
    }


    @PostMapping("/findUserByUid")
    public CommonResult findUserByUid (String uid){
        Users users = usersService.queryUserByUid(uid);
        UsersVO usersVO= new UsersVO();
        BeanUtil.copyProperties(users,usersVO);
        return CommonResult.success(usersVO);
    }

    @PostMapping("/updateUserInfo")
    public CommonResult updateUserInfo(HttpServletRequest request,Users users){
        users.setUid(jwtUtils.getUidFromRequest(request));
        String tokenFromRequest = jwtUtils.getTokenFromRequest(request);
        redisTemplate.opsForValue().set(tokenFromRequest,users);
        usersService.updateUserInfoById(users);
        return CommonResult.success(null);
    }

    @PostMapping("/logOut")
    public CommonResult logOut(HttpServletRequest request){
        Boolean delete = redisTemplate.delete(jwtUtils.getTokenFromRequest(request));
        return CommonResult.success(delete);
    }

    @PostMapping("/authToken")
    public CommonResult authToken(HttpServletRequest request){
        jwtUtils.verifyToken(jwtUtils.getTokenFromRequest(request));
        return CommonResult.success("成功！");
    }
}
